package com.party.mobile.web.controller.gift;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.authorization.annotation.Authorization;
import com.party.common.paging.Page;
import com.party.common.utils.PartyCode;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.coupon.Coupon;
import com.party.core.model.crowdfund.Project;
import com.party.core.model.gift.*;
import com.party.core.model.logistics.WlLogisticsStatus;
import com.party.core.model.logistics.WlParcelOutput;
import com.party.core.model.member.Member;
import com.party.core.model.system.TargetType;
import com.party.core.service.coupon.ICouponService;
import com.party.core.service.crowdfund.IProjectService;
import com.party.core.service.gift.IGiftMemberService;
import com.party.core.service.gift.IGiftOrderService;
import com.party.core.service.gift.IGiftService;
import com.party.core.service.gift.biz.GiftBizService;
import com.party.core.service.logistics.biz.LogisticsBizService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.cos.CosBizService;
import com.party.mobile.biz.currentUser.CurrentUserBizService;
import com.party.mobile.biz.gift.GiftOrderBizService;
import com.party.mobile.biz.gift.GiftTargetBizService;
import com.party.mobile.web.dto.AjaxResult;
import com.party.mobile.web.dto.gift.GiftInput;
import com.party.mobile.web.dto.login.output.CurrentUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @Author: Administrator.
 * @Description: 礼包控制器
 * @Date:Created in 2017/11/16 0016 上午 9:02.
 */
@Controller
@RequestMapping("gift/")
public class GiftController {
    @Autowired
    private IGiftOrderService giftOrderService;
    @Autowired
    private IGiftService giftService;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private CurrentUserBizService currentUserBizService;
    @Autowired
    private GiftOrderBizService giftOrderBizService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private GiftTargetBizService giftTargetBizService;
    @Autowired
    private ICouponService couponService;
    @Autowired
    private CosBizService cosBizService;
    @Autowired
    private IGiftMemberService giftMemberService;
    @Autowired
    private GiftBizService giftBizService;
    @Autowired
    private LogisticsBizService logisticsBizService;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 检查是否有可领取的礼包
     *
     * @param checkInput 检查礼包参数
     * @return
     */
    @ResponseBody
    @Authorization
    @RequestMapping("order/checkGiftOrder")
    public AjaxResult checkGiftOrder(GiftInput checkInput, BindingResult result, HttpServletRequest request) {
        logger.info("检查礼包请求参数：{}", JSONObject.toJSONString(checkInput));
        // 数据验证
        if (result.hasErrors()) {
            List<ObjectError> allErrors = result.getAllErrors();
            String description = allErrors.get(0).getDefaultMessage();
            return AjaxResult.error(100, description);
        }
        try {
            CurrentUser currentUser = currentUserBizService.getCurrentUser(request);
            List<GiftTarget> giftTargets = Lists.newArrayList();
            List<GiftMember> giftMembers = Lists.newArrayList();
            if (checkInput.getType().equals(TargetType.ZC_ACTIVITY.getCode())) {
                Project project = projectService.get(checkInput.getProjectId());
                if (project == null) {
                    return AjaxResult.error(PartyCode.IS_NO_DATA, "众筹不存在");
                }
                giftTargets = giftTargetBizService.zcActivityGiftTarget
                        (checkInput.getTargetId(), project, checkInput.getGiftFlag(), checkInput.getRealPayment(), giftMembers, request);
            }
            List<Map<String, Object>> giftList = Lists.newArrayList();

            for (GiftTarget giftTarget : giftTargets) {
                Gift gift = giftService.get(giftTarget.getGiftId());
                boolean flag = true;
                if (gift.getSalesNum() >= gift.getStock()) { // 已领取总数等于发放总数
                    flag = false;
                } else if (System.currentTimeMillis() < gift.getStartTime().getTime()) { // 未开始
                    flag = false;
                } else if (System.currentTimeMillis() > gift.getEndTime().getTime()) { // 结束
                    flag = false;
                }
                if (flag) {
                    Map<String, Object> map = Maps.newHashMap();
                    map.put("gift", gift);
                    if (Gift.MODEL_INVENTED.equals(gift.getModel())) {
                        List<Coupon> coupons = couponService.findByGiftId(gift.getId());
                        if (coupons.size() == 0) {
                            return AjaxResult.error(100, "礼包券异常");
                        }
                        map.put("coupons", coupons);
                    }
                    giftList.add(map);
                    if (!gift.getModel().equals(Gift.MODEL_ADVERTISE)) {
                        GiftMember giftMember = new GiftMember(gift.getId(), currentUser.getId(), giftTarget.getTargetId(), "", gift.getType());
                        if (TargetType.ZC_ACTIVITY.getCode().equals(gift.getType())) {
                            giftMember.setProjectId(checkInput.getProjectId());
                        }
                        giftMember.setEndTime(gift.getEndTime());
                        giftMemberService.insert(giftMember);
                    }
                }
            }
            List<String> giftIds = giftService.getOverdue(currentUser.getId());
            for (String giftId : giftIds) {
                giftMemberService.deleteByGiftId(giftId);
            }
            return AjaxResult.success(giftList);
        } catch (Exception e) {
            logger.error("检查礼包异常", e);
            return AjaxResult.error();
        }
    }


    /**
     * 领取礼包
     *
     * @param giftId   礼包id
     * @param targetId 项目id
     * @param memberId 用户id
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("order/saveGiftOrder")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult saveGiftOrder(String giftId, String targetId, String memberId, String projectId, HttpServletRequest request) {
        if (StringUtils.isEmpty(giftId)) {
            return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "礼包id不能为空");
        }

        try {
            Gift gift = giftService.get(giftId);
            if (gift == null) {
                return AjaxResult.error(PartyCode.IS_NO_DATA, "礼包数据不存在");
            }
            if (gift.getEndTime().getTime() < System.currentTimeMillis()) {
                return AjaxResult.error(1101, "礼包已过期，不能领取");
            }
            CurrentUser currentUser = currentUserBizService.getCurrentUser(request);
            String currentId = StringUtils.isNotEmpty(memberId) ? memberId : currentUser.getId();
            if (gift.getType().equals(TargetType.ZC_ACTIVITY.getCode())) {
                // 众筹报名/众筹成功只能领一次
                if (gift.getCondition().equals(TargetCondition.ZC_SUCCESS.getCode())
                        || gift.getCondition().equals(TargetCondition.ZC_APPLY.getCode())) {
                    GiftOrder giftOrder = giftOrderService.getUnique(new GiftOrder(currentId, giftId, targetId));
                    if (giftOrder != null) {
                        return AjaxResult.error(1101, "礼包已经领取过了");
                    }
                }
            }

            if (gift.getSalesNum() >= gift.getStock()) {
                return AjaxResult.error(1101, "礼包库存不足");
            }
            giftOrderBizService.payOrder(currentId, targetId, gift, projectId);
            return AjaxResult.success();
        } catch (BusinessException e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(119, "礼包领取失败");
        } catch (Exception e) {
            logger.error("礼包领取异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(110, "礼包领取失败");
        }
    }

    /**
     * 礼包详细
     *
     * @param giftInput    请求参数
     * @param newProjectId 用来跳转到众筹页面
     * @return
     */
    @ResponseBody
    @Authorization
    @RequestMapping("gift/getDetail")
    public AjaxResult getDetail(GiftInput giftInput, String newProjectId, HttpServletRequest request) {
        if (StringUtils.isEmpty(giftInput.getGiftId())) {
            return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "礼包id不能为空");
        }
        if (StringUtils.isEmpty(giftInput.getTargetId())) {
            return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "项目id不能为空");
        }
        if (StringUtils.isEmpty(giftInput.getType())) {
            return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "礼包应用场景不能为空");
        }
        try {
            CurrentUser currentUser = currentUserBizService.getCurrentUser(request);
            Map<String, Object> resultMap = Maps.newHashMap();
            Gift gift = giftService.get(giftInput.getGiftId());
            if (Gift.MODEL_INVENTED.equals(gift.getModel())) {
                List<Coupon> coupons = couponService.findByGiftId(giftInput.getGiftId());
                if (coupons.size() == 0) {
                    return AjaxResult.error(100, "礼包券异常");
                }
                resultMap.put("coupons", coupons);
            }

            if (TargetType.ZC_ACTIVITY.getCode().equals(giftInput.getType())) {
                if (StringUtils.isEmpty(giftInput.getProjectId())) {
                    return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "众筹id不能为空");
                }
                Project myProject = projectService.findByTargetWithAuthor(giftInput.getTargetId(), currentUser.getId());
                resultMap.put("myProject", myProject);
                if (TargetCondition.ZC_SUPPORT.getCode().equals(gift.getCondition())) {
                    // 众筹者
                    Project project = projectService.get(giftInput.getProjectId());
                    Member author = memberService.get(project.getAuthorId());
                    resultMap.put("author", author); // 众筹者
                    resultMap.put("targetProjectId", giftInput.getProjectId());
                }
                resultMap.put("projectId", newProjectId); // 众筹id
            }

            resultMap.put("gift", gift); // 礼包实体
            resultMap.put("targetId", giftInput.getTargetId()); // 项目id
            return AjaxResult.success(resultMap);
        } catch (Exception e) {
            logger.error("礼包详情异常", e);
            return AjaxResult.error();
        }
    }

    /**
     * 礼包前端详情
     *
     * @param giftInput
     * @return
     */
    @ResponseBody
    @Authorization
    @RequestMapping("gift/getFrontDetail")
    public AjaxResult getFrontDetail(GiftInput giftInput) {
        if (StringUtils.isEmpty(giftInput.getGiftId())) {
            return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "礼包id不能为空");
        }

        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            Gift gift = giftService.get(giftInput.getGiftId());
            if (Gift.MODEL_INVENTED.equals(gift.getModel())) {
                List<Coupon> coupons = couponService.findByGiftId(giftInput.getGiftId());
                if (coupons.size() == 0) {
                    return AjaxResult.error(100, "礼包券异常");
                }
                resultMap.put("coupons", coupons);
            }

            resultMap.put("gift", gift); // 礼包实体
            return AjaxResult.success(resultMap);
        } catch (Exception e) {
            logger.error("礼包详情异常", e);
            return AjaxResult.error();
        }
    }

    /**
     * 礼包领取详情
     *
     * @param giftId   礼包id
     * @param targetId 项目id
     * @param request
     * @return
     */
    @ResponseBody
    @Authorization
    @RequestMapping("order/getDetail")
    public AjaxResult getOrderDetail(String giftId, String targetId, HttpServletRequest request) {
        if (StringUtils.isEmpty(giftId)) {
            return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "礼包id不能为空");
        }
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            CurrentUser currentUser = currentUserBizService.getCurrentUser(request);
            Gift gift = giftService.get(giftId);
            if (gift == null) {
                return AjaxResult.error(PartyCode.IS_NO_DATA, "礼包数据不存在");
            }
            GiftOrder giftOrder = giftOrderService.getUnique(new GiftOrder(currentUser.getId(), giftId, targetId));
            if (giftOrder == null) {
                return AjaxResult.error(PartyCode.IS_NO_DATA, "礼包领取信息不存在");
            }
            resultMap.put("giftOrder", giftOrder);
            resultMap.put("gift", gift);
            if (TargetType.ZC_ACTIVITY.getCode().equals(gift.getType())) {
                Project myProject = projectService.findByTargetWithAuthor(targetId, currentUser.getId());
                resultMap.put("myProject", myProject);
                if (Gift.MODEL_INVENTED.equals(gift.getModel())) { // 虚拟礼包获取券信息
                    String filePath = String.format(GiftOrder.UPLOAD_URL, currentUser.getId());
                    String qrcodeUrl = cosBizService.getPreviewPictureUrl(filePath + giftOrder.getCouponCodeId());
                    Map<String, Object> couponMap = couponService.findByOrderId(giftOrder.getId());
                    couponMap.put("qrcodeUrl", qrcodeUrl);
                    resultMap.put("coupon", couponMap);
                } else if (Gift.MODEL_MATTER.equals(gift.getModel())) { // 实物礼包物流信息
                    WlParcelOutput parcelOut = logisticsBizService.getParcelByTargetId(giftOrder.getId());
                    if (parcelOut != null) {
                        resultMap.put("logisticsStatus", parcelOut.getStatus());
                        resultMap.put("logisticsStatusName", WlLogisticsStatus.getValue(parcelOut.getStatus()));
                        resultMap.put("logisticsParcelId", parcelOut.getParcelId());
                    } else {
                        resultMap.put("logisticsStatus", WlLogisticsStatus.NOT_SHIPMENT.getCode());
                        resultMap.put("logisticsStatusName", WlLogisticsStatus.NOT_SHIPMENT.getName());
                    }
                }
            }
            return AjaxResult.success(resultMap);
        } catch (Exception e) {
            logger.error("详情异常", e);
            return AjaxResult.error();
        }
    }

    /**
     * 礼包列表
     *
     * @param request
     * @param isOrder 是否领取
     * @param page
     * @return
     */
    @ResponseBody
    @Authorization
    @RequestMapping("gift/list")
    public AjaxResult giftList(HttpServletRequest request, Integer isOrder, Page page) {
        CurrentUser currentUser = currentUserBizService.getCurrentUser(request);
        List<GiftListOut> giftListOutputs = giftService.findAllByMemberId(currentUser.getId(), isOrder, page);
        for (GiftListOut output : giftListOutputs) {
            String authorName = giftBizService.getTargetAuthor(output.getType(), output.getTargetId());
            output.setAuthorName(authorName);
        }
        return AjaxResult.success(giftListOutputs, page);
    }

    /**
     * 检查是否拥有礼包
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("gift/checkHasGift")
    public AjaxResult checkHasGift(HttpServletRequest request) {
        try {
            CurrentUser currentUser = currentUserBizService.getCurrentUser(request);
            List<GiftListOut> giftListOutputs = giftService.findAllByMemberId(currentUser.getId(), null, null);
            Boolean result = giftListOutputs.size() > 0 ? true : false;
            return AjaxResult.success(result);
        } catch (Exception e) {
            return AjaxResult.error();
        }
    }

    /**
     * 根据编号获取礼包信息
     *
     * @param giftId 礼包id
     * @return
     */
    @ResponseBody
    @RequestMapping("getGiftInfo")
    public AjaxResult getGiftInfo(String giftId) {
        if (StringUtils.isEmpty(giftId)) {
            return AjaxResult.error(PartyCode.PARAMETER_ILLEGAL, "礼包id不能为空");
        }
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            Gift gift = giftService.get(giftId);
            if (Gift.MODEL_INVENTED.equals(gift.getModel())) {
                List<Coupon> coupons = couponService.findByGiftId(giftId);
                if (coupons.size() == 0) {
                    return AjaxResult.error(100, "礼包券异常");
                }
                resultMap.put("coupons", coupons);
            }
            resultMap.put("gift", gift);
            return AjaxResult.success(resultMap);
        } catch (Exception e) {
            return AjaxResult.error(1000, "获取礼包信息异常");
        }
    }
}
